package scuts.core.lifting;

import scuts.core.types.Either;
import scuts.core.types.ProgressiveFuture;
import utest.Assert;


using scuts.core.lifting.EitherLifting;

using scuts.core.extensions.Eithers;

using scuts.core.Compose;

using scuts.core.lifting.ProgressiveFutureLifting;

class EitherLiftingTest
{

  public function new() 
  {
    
  }
  
  public function testLiftWithEither () {
    var f = function (a:Int) return a + 1;
    
    var either = Left(5);
    
    var res = f.liftWithEitherLeft()(either);
   
    
    Assert.isTrue(res.isLeft());
    Assert.equals(6, res.left());
    
    
  }
  
  public function testLiftWithEitherLeftAndRightComposed () {
    var f1 = function (a:Int) return a + 1;
    
    var f2 = function (e:String) return "Error: " + e;
    
    var left = Left(5);
    var right = Right("Cannot load file");
    
    var concatF = f1.liftWithEitherLeft().compose(f2.liftWithEitherRight());
    
    var res1 = concatF(left);
   
    Assert.isTrue(res1.isLeft());
    Assert.equals(6, res1.left());
    
    var res2 = concatF(right);
    
    Assert.isTrue(res2.isRight());
    Assert.equals("Error: Cannot load file", res2.right());
    
  }
  
  public function testLiftWithEitherLeftAndRightComposedAndFuture () 
  {
    var f1 = function (a:Int) return a + 1;
    
    var f2 = function (e:String) return "Error: " + e;
    
    var fut1 = new ProgressiveFuture();
    var fut2 = new ProgressiveFuture();
    
    var left = Left("Cannot load file");
    var right = Right(5);
    
    var concatF = f1.liftWithEitherRight().compose(f2.liftWithEitherLeft()).liftWithProgressiveFuture();
    
    var res1 = concatF(fut1);
    fut1.deliver(left);
    
    Assert.isTrue(res1.isDelivered());
    Assert.isTrue(res1.value().isLeft());
    Assert.equals("Error: Cannot load file", res1.value().left());
    
    var res2 = concatF(fut2);
    fut2.deliver(right);
    
    Assert.isTrue(res2.isDelivered());
    Assert.isTrue(res2.value().isRight());
    Assert.equals(6, res2.value().right());
    
  }
  
}